home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / lanutsrc.zip / MSET.C < prev    next >
Text File  |  1991-10-23  |  5KB  |  205 lines

  1. /**********************************************************************
  2.  NOTE: MSET follows the memory control block chain to find the first
  3.        copy of COMMAND.COM.  This technique works reliably only with
  4.        DOS 3.3 and earlier.  For a much better way to set things in the
  5.        master environment, see Andrew Schulman's "Undocumented DOS". 
  6. ************************************************************************/
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <dos.h>
  11. #include <string.h>
  12.  
  13. #include "lantasti.h"
  14.  
  15. #define MK_FP(seg,ofs)    ((void far *) \
  16.                (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  17.                
  18.                
  19. /* psp and memory control structures */
  20. typedef struct {
  21.     char misc1[22];
  22.     unsigned int parent_seg;
  23.     char misc2[20];
  24.     unsigned int env_seg;
  25.   } PSP;
  26.   
  27. typedef struct {
  28.     char status;                /* block currently in use? */
  29.     unsigned int owners_psp;    /* segment of owner's PSP */
  30.     unsigned int size;          /* in paragraphs */
  31.   } MCB;
  32.  
  33. /* global environment info */
  34. char far *par_env;
  35. int par_env_len;
  36.  
  37. /* get_parent_envp **********************************************************
  38.  Returns a pointer to the calling process' environment block
  39. *****************************************************************************/
  40. void get_parent_envp()
  41. {
  42.   union REGS regs;
  43.   struct SREGS sregs; 
  44.   
  45.   PSP far *cmd_psp;
  46.   MCB far *cmd_mcb,far *env_mcb, far *config_mcb;
  47.   int far *seg_ptr;
  48.   
  49.   regs.x.ax = 0x5200;
  50.   intdosx(®s, ®s, &sregs);
  51.  
  52.   seg_ptr = MK_FP(sregs.es, regs.x.bx - 2);
  53.   config_mcb = MK_FP(*seg_ptr, 0);
  54.  
  55.   cmd_psp = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 2, 0);
  56.  
  57.   if (cmd_psp->env_seg == 0) {
  58.         /* Environment is in block after parent program    */
  59.     cmd_mcb = MK_FP(FP_SEG(config_mcb) + config_mcb->size + 1, 0);
  60.     par_env = MK_FP(FP_SEG(cmd_mcb) + cmd_mcb->size + 2, 0);
  61.   }
  62.   else  /* We have pointer to environment     */
  63.     par_env = MK_FP(cmd_psp->env_seg, 0);
  64.  
  65.    /* MCB of environment is 1 segment lower */
  66.  
  67.    env_mcb = MK_FP(FP_SEG(par_env) - 1, 0);
  68.  
  69.    par_env_len = env_mcb->size * 16; 
  70.  
  71. }
  72.  
  73. /* del_par_env ********************************************************************
  74.  
  75. *****************************************************************************/
  76. void del_par_env(env_var)
  77.   char *env_var;
  78. {
  79.  
  80.     char far *far1;        /* Beginning of next variable    */
  81.     char far *far2;        /* Beginning of the variable    */
  82.     char *str;        /* env_var ptr used in search    */
  83.  
  84.     int found = FALSE;    /* End of search flag        */
  85.  
  86.     far1 = par_env;
  87.  
  88.     while(*far1 && !found)
  89.     {                                                /* Find start of variable to delete    */
  90.         str = env_var;
  91.         far2 = far1;
  92.         for(;(*far1 == *str) && (*far1 != '=') && *far1 && *str; ++far1, ++str)
  93.             ;
  94.         if((!*str) && (*far1 == '='))
  95.             found = TRUE;            /* We found it!            */
  96.         for(; *far1; ++far1)
  97.             ;
  98.         ++far1;
  99.     }
  100.  
  101.     if(!*far1 && !found)            /* Find env_var?            */
  102.         return;                /* No, we didn't            */
  103.  
  104. /* Shift environment down, to cover env_var            */
  105.  
  106.     for(; !(!*far1 && !*(far1+1)); *far2++ = *far1++)
  107.         ;
  108.  
  109.     *far2 = 0;    /* End env with 2 nulls */
  110.     ++far2;
  111.     *far2 = 0;
  112. }
  113.  
  114. /* put_par_env ********************************************************************
  115.  
  116. *****************************************************************************/
  117. void put_par_env(env_var,env_text)
  118.   char far *env_var,*env_text;
  119. {
  120.  
  121.     char far *far0;
  122.     int len;
  123.     char env_str[256];
  124.     char *str;
  125.  
  126. /* build environment string */
  127.     strcpy(env_str, env_var);
  128.     strcat(env_str, "=");
  129.     strcat(env_str, env_text);
  130.  
  131. /* delete old environment variable */
  132.     del_par_env(env_var);     
  133.  
  134. /* Find end of environment by looking for 2 NULLS */
  135.     for(far0 = par_env, len = 0; !(!*far0 && !*(far0+1)); ++far0, ++len)
  136.         ;
  137.  
  138. /* get amount of remaining free space in env. block */
  139.     len = par_env_len - (len + 2);            
  140.  
  141.     if(len < strlen(env_str) + 1)
  142.     {                                                /* If out of room, return error    */
  143.       puts("Out of environment space.");
  144.       return;
  145.     }
  146.  
  147.     str = env_str;
  148.  
  149. /* add new variable to end of environment */
  150.     for(++far0; *str; *far0++ = *str++) 
  151.         ;
  152.         
  153. /* terminate with two nulls */
  154.     *far0 = 0;      
  155.     ++far0;
  156.     *far0 = 0;
  157.  
  158. }
  159.  
  160. /*     ********************************************************************
  161.  MSET - Sets a variable in the lowest level (MASTER) environment.
  162. *****************************************************************************/
  163. main(argc,argv)
  164.   int argc;
  165.   char *argv[];
  166. {
  167.   int i;
  168.   char vname[40],value[256];
  169.   char *tok;
  170.   
  171.   if (argc < 2) {
  172.     puts("MSET - Sets variables in the master environment.\n");
  173.     puts("Usage: Same as the built in SET command -- for example");
  174.     puts("MSET PATH=C:\;C:\UTILITY\n");
  175.     puts("Copyright 1989 by SoftMagic, Inc.  All rights reserved.");
  176.     exit(0);
  177.   }
  178.  
  179. /* first, change the variable in the local environment */
  180.   putenv(argv[1]);  
  181.   
  182. /* now change the master environment */
  183.   tok = strtok(argv[1],"=");    /* get the variable name */
  184.   if (strlen(tok) > 39) {
  185.     puts("Invalid variable name -- give me a break!");
  186.     exit(-1);
  187.   }
  188.   else strcpy(vname,tok);
  189.   strupr(vname);
  190.    
  191.   get_parent_envp();
  192.   
  193.   tok = strtok(NULL," ");
  194.   if (tok == NULL) del_par_env(vname);
  195.   else {
  196.     strcpy(value,tok);
  197.     for (i = 2;i < argc; i++) {
  198.       strcat(value," ");
  199.       strcat(value,argv[i]);
  200.     }
  201.     put_par_env(vname,value);
  202.   }
  203.  
  204. }
  205.